#include "quadtree.h"
#include <iostream>

Quadtree::~Quadtree()
{
	std::vector<Node*>::iterator it;
	for (it = allNode.begin(); it != allNode.end(); )
	{
		delete(*it);
		it = allNode.erase(it);
	}
}

void Quadtree::AddNode(Node *ancestor)
{
	int x1 = ancestor->GetTlX();
	int y1 = ancestor->GetTlY();
	int x2 = ancestor->GetBrX();
	int y2 = ancestor->GetBrY();
	int x12 = (x2 - x1) / 2 + x1;
	int y12 = (y2 - y1) / 2 + y1;
	int level = ancestor->GetNodeLevel() + 1;
	
	Node *leaf1 = new Node(x1, y1, x12, y12, level, ancestor);
	Node *leaf2 = new Node(x12 + 1, y1, x2, y12, level, ancestor);
	Node *leaf3 = new Node(x1, y12 + 1, x12, y2, level, ancestor);
	Node *leaf4 = new Node(x12 + 1, y12 + 1, x2, y2, level, ancestor);
	
	leaf1->InheritAdjacentMatrixTop(ancestor->ReturnAdjacentMatrixTop());
	leaf1->AddNeighbourRight(leaf2);
	leaf1->AddNeighbourBottom(leaf3);
	leaf1->InheritAdjacentMatrixLeft(ancestor->ReturnAdjacentMatrixLeft());
	
	leaf2->InheritAdjacentMatrixTop(ancestor->ReturnAdjacentMatrixTop(), false);
	leaf2->InheritAdjacentMatrixRight(ancestor->ReturnAdjacentMatrixRight());
	leaf2->AddNeighbourBottom(leaf4);
	leaf2->AddNeighbourLeft(leaf1);
	
	leaf3->AddNeighbourTop(leaf1);
	leaf3->AddNeighbourRight(leaf4);
	leaf3->InheritAdjacentMatrixBottom(ancestor->ReturnAdjacentMatrixBottom());
	leaf3->InheritAdjacentMatrixLeft(ancestor->ReturnAdjacentMatrixLeft(), false);
	
	leaf4->AddNeighbourTop(leaf2);
	leaf4->InheritAdjacentMatrixRight(ancestor->ReturnAdjacentMatrixRight(), false);
	leaf4->InheritAdjacentMatrixBottom(ancestor->ReturnAdjacentMatrixBottom(), false);
	leaf4->AddNeighbourLeft(leaf3);
	
	ancestor->RemoveAdjacentMatrix();
	ancestor->SetColored(true);
	
	allNode.push_back(leaf1);
	allNode.push_back(leaf2);
	allNode.push_back(leaf3);
	allNode.push_back(leaf4);
}

void Quadtree::ReInit()
{
	std::vector<Node*>::iterator it;
	for (it = allNode.begin() + 1; it != allNode.end(); )
	{
		delete(*it);
		it = allNode.erase(it);
	}
}

void Quadtree::Display(IplImage *img)
{
	CvScalar pixel;
	pixel.val[0] = 255;
	
	std::vector<Node*>::const_iterator it;
	for (it = allNode.begin(); it != allNode.end(); it++)
	{
		for (int i = (*it)->GetTlX() ; i <= (*it)->GetBrX(); i++)
		{
			for (int j = (*it)->GetTlY() ; j <= (*it)->GetBrY() ; j++)
			{
				if (i == (*it)->GetTlX() || j == (*it)->GetTlY())
					cvSet2D(img, j, i, pixel);
			}
		}
	}
}

void Quadtree::Display()
{
	int i = 0;
	std::vector<Node*>::const_iterator it;
	for (it = allNode.begin(); it != allNode.end(); ++it)
	{
		std::cout << "Noeud " << i << " : " << std::endl;
		std::cout << "tl_x : " << (*it)->GetTlX() << " , tl_y : " << (*it)->GetTlY() << std::endl;
		std::cout << "br_x : " << (*it)->GetBrX() << " , br_y : " << (*it)->GetBrY() << std::endl;
		std::cout << "level : " << (*it)->GetNodeLevel() << std::endl << std::endl;
		++i;
	}
}


void Quadtree::Display(Node *node)
{
	std::cout << "tl_x : " << node->GetTlX() << " , tl_y : " << node->GetTlY() << std::endl;
	std::cout << "br_x : " << node->GetBrX() << " , br_y : " << node->GetBrY() << std::endl;
	std::cout << "level : " << node->GetNodeLevel() << std::endl << std::endl;
}






